package com.zxd.interview.conrruentbook;

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * 定时任务类
 * @author Xander
 * @version v1.0.0
 * @Package : com.zxd.interview.cocurrent
 * @Description : 定时任务类
 * @Create on : 2023/6/14 20:30
 **/
public class TimerTask implements Delayed, Runnable  {
    /**
     * <pre>
     * 延迟时长，出队时判断数据在队列中
     * 是否达到了interval时长
     * 如果未达到interval时长，则继续等待
     * 如果已达到interval时长，则出队
     * </pre>
     */
    private long interval;

    /**
     * <pre>
     * 数据放入队列的时间
     * 结合系统当前时间判断元素
     *  是否已经达到延迟时间
     * </pre>
     */
    private long queueTime;

    /**
     * 延迟队列
     */
    private DelayQueue<TimerTask> delayQueue;
    /**
     * 执行的任务
     */
    private Runnable task;

    public TimerTask(DelayQueue<TimerTask> delayQueue, Runnable task,  long interval) {
        this.interval = interval;
        this.delayQueue = delayQueue;
        this.task = task;
    }

    @Override
    public void run() {
        //执行具体的任务
        task.run();
        //每次执行任务时，更新time时间
        queueTime = System.currentTimeMillis();
        delayQueue.put(this);
    }

    @Override
    public long getDelay(TimeUnit unit) {
        // 实际就是计算 INTERVAL 的对应值
        long convert = unit.convert((this.queueTime + this.interval) - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
        return convert;
    }

    /**
     * 根据数据放入队列的时间进行排序
     * compareTo 方法必须提供与 getDelay 方法一致的排序
     * @param o the object to be compared.
     * @return
     */
    @Override
    public int compareTo(Delayed o) {
        int i = (int) (this.queueTime - ((TimerTask) o).getQueueTime());
        return i;
    }

    public long getQueueTime() {
        return queueTime;
    }
}
